/*
 * main.cpp
 *
 *  Created on: Nov 28, 2009
 */

#include "common/utils/StringUtils.h"
#include "image/api/ImageEntity.h"
#include "image/impl/ImageController.h"
#include "filter/impl/HighBoost.h"
#include "filter/impl/Roberts.h"
#include "filter/impl/Sobel.h"
#include "filter/impl/LowPass.h"
#include "filter/impl/Mediana.h"


#include <iostream>
#include <string>
#include <mpi.h>

using namespace std;

void executeHightBoost(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *highBoost = new HighBoost(1);
	ImageEntity *highImage = highBoost->apply(image);

	if (highImage != NULL) {
		string hight = "_hightBoost";
		hight.append(imagePath);
		controller->saveImage(imagePath,  hight, highImage);
		delete highBoost;
		delete highImage;
	}
}

void executeRoberts(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *roberts = new Roberts(60);
	ImageEntity *robertsImage = roberts->apply(image);

	if (robertsImage != NULL) {
		string robertsOut = "_roberts";
		robertsOut.append(imagePath);
		controller->saveImage(imagePath, robertsOut, robertsImage);
		delete robertsImage;
		delete roberts;
	}
}

void executeSobel(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *sobel = new Sobel(60);
	ImageEntity *sobelImage = sobel->apply(image);

	if (sobelImage != NULL) {
		string sobelOut = "_sobel";
		sobelOut.append(imagePath);
		controller->saveImage(imagePath, sobelOut, sobelImage);
		delete sobelImage;
		delete sobel;
	}
}

void media(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *lowPass = new LowPass();
	ImageEntity *lowImage = lowPass->apply(image);

	if (lowImage != NULL) {
		string lowOut = "_media";
		lowOut.append(imagePath);
		controller->saveImage(imagePath, lowOut, lowImage);
		delete lowImage;
		delete lowPass;
	}
}

void mediana(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *mediana = new Mediana();
	ImageEntity *medianaImage = mediana->apply(image);

	if (medianaImage != NULL) {
		string medianaOut = "_mediana";
		medianaOut.append(imagePath);
		controller->saveImage(imagePath, medianaOut, medianaImage);
		delete medianaImage;
		delete mediana;
	}
}

int main(int argc, char **argv) {
	if (argc < 3) {
		cout << "filter <type> <imagePath>" << endl;
		cout << endl;
		cout << "type:" << endl;
		cout << "1 - Alto Reforco" << endl;
		cout << "2 - Roberts" << endl;
		cout << "3 - Sobel" << endl;
		cout << "4 - Media" << endl;
		cout << "5 - Mediana" << endl;

		return 1;
	}


	string imagePath = argv[2];
	string type = argv[1];

	//	EXECUTE FILTERS
	MPI_Init(&argc, &argv);
		if (type == "1") {
			executeHightBoost(imagePath);
		} else if (type == "2") {
			executeRoberts(imagePath);
		} else if (type == "3") {
			executeSobel(imagePath);
		} else if (type == "4") {
			media(imagePath);
		} else {
			mediana(imagePath);
		}

	MPI_Finalize();

	return 0;
}
